package com.gamemost.libepub;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import com.gamemost.templestay.Config;

import android.util.Xml;

public class StackOverflowXmlParser {
	private static final String ns = null;
	XmlPullParser parser;
	private String header = "";

	public StackOverflowXmlParser(InputStream in)
			throws XmlPullParserException, IOException {
		parser = Xml.newPullParser();
		parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
		parser.setInput(in, null);
		parser.nextTag();
		parser.nextTag();
		String tag = parser.getName();
		String[] t = tag.split(":");
		if (t.length > 1)
			header = t[0] + ":";
	}

	public static String readMetaInf(InputStream in)
			throws XmlPullParserException, IOException {
		String root = "";
		try {
			XmlPullParser parser = Xml.newPullParser();
			parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
			parser.setInput(in, null);
			parser.nextTag();
			parser.nextTag();
			parser.require(XmlPullParser.START_TAG, ns, "rootfiles");
			while (parser.next() != XmlPullParser.END_TAG
					|| !"rootfiles".equals(parser.getName())) {
				if (parser.getEventType() != XmlPullParser.START_TAG) {
					continue;
				}
				String name = parser.getName();
				// Starts by looking for the entry tag
				if (name.equals("rootfile")) {
					root = parser.getAttributeValue(null, "full-path");
				}
			}
		} finally {
			in.close();
		}
		return root;
	}

	public Book readMetadata() throws XmlPullParserException, IOException {
		Book aBook = new Book();
		parser.require(XmlPullParser.START_TAG, ns, header + "metadata");
		while (parser.next() != XmlPullParser.END_TAG
				|| !(header + "metadata").equals(parser.getName())) {
			if (parser.getEventType() != XmlPullParser.START_TAG) {
				continue;
			}
			String name = parser.getName();
			// Starts by looking for the entry tag
			if (name.equals("dc:title")) {
				aBook.setTitle(readText(parser));
			} else if (name.equals("dc:creator")) {
				aBook.setAuthor(readText(parser));
			} else if (name.equals("dc:publisher")) {
				aBook.setPublisher(readText(parser));

			} else if (name.equals("dc:date")) {
				aBook.setDate(readText(parser));

			} else if (name.equals("meta")) {
				String att = parser.getAttributeValue(null, "property");
				if (att != null && att.contains("layout")) {
					aBook.setLayout(parser.getText());
				}

			} else {
				skip(parser);
			}
		}
		return aBook;
	}

	public NSDictionary readItemList() throws XmlPullParserException,
			IOException {
		NSDictionary dic = new NSDictionary();
		while (!(header + "manifest").equals(parser.getName())) {
			parser.nextTag();
		}
		parser.require(XmlPullParser.START_TAG, ns, header + "manifest");
		while (parser.next() != XmlPullParser.END_TAG
				|| !(header + "manifest").equals(parser.getName())) {
			if (parser.getEventType() != XmlPullParser.START_TAG) {
				continue;
			}
			String name = parser.getName();
			// Starts by looking for the entry tag
			if (name.equals(header + "item")) {
				String id = parser.getAttributeValue(null, "id");
				String href = parser.getAttributeValue(null, "href");
				String mediaType = parser.getAttributeValue(null, "media-type");

				Item aItem = new Item(id, href, mediaType);
				dic.addItem(aItem);
			} else {
				skip(parser);
			}
		}
		return dic;
	}

	public TableOfContent readTableOfContent() throws XmlPullParserException,
			IOException {
		TableOfContent tableContent = new TableOfContent();
		while (!(header+"spine").equals(parser.getName())) {
			parser.nextTag();
		}
		parser.require(XmlPullParser.START_TAG, ns, header + "spine");
		while (parser.next() != XmlPullParser.END_TAG
				|| !(header + "spine").equals(parser.getName())) {
			if (parser.getEventType() != XmlPullParser.START_TAG) {
				continue;
			}
			String name = parser.getName();
			// Starts by looking for the entry tag
			if (name.equals(header+"itemref")) {
				ItemRef aItemRef = new ItemRef();
				String id = parser.getAttributeValue(null, "idref");
				aItemRef.setIdref(id);
				tableContent.addItem(aItemRef);
				String properties = parser
						.getAttributeValue(null, "properties");
				if (properties != null) {
					if (properties.contains("layout-pre-paginated")) {
						aItemRef.setCodeLayout(Config.FIX_LAYOUT);
					} else if (properties.contains("layout-reflowable")) {
						aItemRef.setCodeLayout(Config.REFLOW_LAYOUT);
					}
				}
			} else {
				skip(parser);
			}
		}
		return tableContent;
	}	

	private void skip(XmlPullParser parser) throws XmlPullParserException,
			IOException {
		if (parser.getEventType() != XmlPullParser.START_TAG) {
			throw new IllegalStateException();
		}
		int depth = 1;
		while (depth != 0) {
			switch (parser.next()) {
			case XmlPullParser.END_TAG:
				depth--;
				break;
			case XmlPullParser.START_TAG:
				depth++;
				break;
			}
		}
	}
	
	public static class Entry {
		public final String title;
		public final String link;
		public final String summary;

		private Entry(String title, String summary, String link) {
			this.title = title;
			this.summary = summary;
			this.link = link;
		}
	}

	private String readText(XmlPullParser parser) throws IOException,
			XmlPullParserException {
		String result = "";
		if (parser.next() == XmlPullParser.TEXT) {
			result = parser.getText();
			parser.nextTag();
		}
		return result;
	}
}
